"""
工单模型
支持工单系统的核心数据模型
"""

from datetime import datetime
from typing import Optional, List, Dict, Any
import uuid
from enum import Enum
from pydantic import BaseModel, Field, model_validator
from sqlalchemy import Column, String, DateTime, Text, ForeignKey, Enum as SQLEnum, Boolean, Integer
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import JSON
from sqlalchemy.orm import relationship
from src.config.database import Base
from src.models.user import User


class TicketStatus(str, Enum):
    """工单状态枚举"""
    OPEN = "open"              # 已打开
    IN_PROGRESS = "in_progress" # 处理中
    RESOLVED = "resolved"      # 已解决
    CLOSED = "closed"          # 已关闭
    REOPENED = "reopened"      # 重新打开


class TicketPriority(str, Enum):
    """工单优先级枚举"""
    LOW = "low"        # 低优先级
    MEDIUM = "medium"  # 中优先级
    HIGH = "high"      # 高优先级
    URGENT = "urgent"  # 紧急优先级


class TicketCategory(str, Enum):
    """工单分类枚举"""
    TECHNICAL = "technical"    # 技术问题
    BILLING = "billing"        # 账单问题
    GENERAL = "general"        # 一般咨询
    BUG = "bug"                # Bug报告
    FEATURE_REQUEST = "feature_request" # 功能请求
    OTHER = "other"            # 其他


class TicketSource(str, Enum):
    """工单来源枚举"""
    WEB = "web"                # 网页端
    EMAIL = "email"            # 邮件
    PHONE = "phone"            # 电话
    CHAT = "chat"              # 在线聊天
    API = "api"                # API接口


class Ticket(Base):
    """工单数据模型"""
    __tablename__ = "tickets"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    title = Column(String(200), nullable=False, index=True)
    description = Column(Text, nullable=False)
    status = Column(SQLEnum(TicketStatus), default=TicketStatus.OPEN, nullable=False, index=True)
    priority = Column(SQLEnum(TicketPriority), default=TicketPriority.MEDIUM, nullable=False, index=True)
    category = Column(SQLEnum(TicketCategory), default=TicketCategory.GENERAL, nullable=False, index=True)
    source = Column(SQLEnum(TicketSource), default=TicketSource.WEB, nullable=False)
    
    # 关联用户
    created_by_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False, index=True)
    assigned_to_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True, index=True)
    
    # 时间信息
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    resolved_at = Column(DateTime, nullable=True)
    closed_at = Column(DateTime, nullable=True)
    
    # 统计信息
    reply_count = Column(Integer, default=0, nullable=False)
    first_response_time = Column(Integer, nullable=True)  # 首次响应时间（秒）
    resolution_time = Column(Integer, nullable=True)      # 解决时间（秒）
    
    # 元数据
    tags = Column(JSON, default=list, nullable=True)     # 标签列表
    custom_fields = Column(JSON, default=dict, nullable=True)  # 自定义字段
    ticket_metadata = Column(JSON, default=dict, nullable=True) # 额外元数据
    
    # 关系
    created_by = relationship("User", foreign_keys=[created_by_id])
    assigned_to = relationship("User", foreign_keys=[assigned_to_id])
    replies = relationship("TicketReply", back_populates="ticket", cascade="all, delete-orphan")


class TicketReply(Base):
    """工单回复数据模型"""
    __tablename__ = "ticket_replies"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    ticket_id = Column(UUID(as_uuid=True), ForeignKey('tickets.id'), nullable=False, index=True)
    user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True, index=True)
    
    content = Column(Text, nullable=False)
    is_internal = Column(Boolean, default=False, nullable=False)  # 是否为内部备注
    is_automated = Column(Boolean, default=False, nullable=False) # 是否为自动回复
    
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # 关系
    ticket = relationship("Ticket", back_populates="replies")
    user = relationship("User")


class TicketCreate(BaseModel):
    """创建工单的请求模型"""
    title: str = Field(..., min_length=1, max_length=200, description="工单标题")
    description: str = Field(..., min_length=2, description="工单描述")
    priority: TicketPriority = Field(default=TicketPriority.MEDIUM, description="优先级")
    category: TicketCategory = Field(default=TicketCategory.GENERAL, description="分类")
    tags: Optional[List[str]] = Field(default=None, description="标签列表")
    custom_fields: Optional[Dict[str, Any]] = Field(default=None, description="自定义字段")


class TicketUpdate(BaseModel):
    """更新工单的请求模型"""
    title: Optional[str] = Field(None, min_length=1, max_length=200, description="工单标题")
    description: Optional[str] = Field(None, min_length=2, description="工单描述")
    status: Optional[TicketStatus] = Field(None, description="工单状态")
    priority: Optional[TicketPriority] = Field(None, description="优先级")
    category: Optional[TicketCategory] = Field(None, description="分类")
    assigned_to_id: Optional[uuid.UUID] = Field(None, description="分配给的用户ID")
    tags: Optional[List[str]] = Field(None, description="标签列表")
    custom_fields: Optional[Dict[str, Any]] = Field(None, description="自定义字段")


class TicketReplyCreate(BaseModel):
    """创建工单回复的请求模型"""
    content: str = Field(..., min_length=1, description="回复内容")
    is_internal: bool = Field(default=False, description="是否为内部备注")
    is_automated: bool = Field(default=False, description="是否为自动回复")


class TicketResponse(BaseModel):
    """工单响应模型"""
    id: uuid.UUID
    title: str
    description: str
    status: TicketStatus
    priority: TicketPriority
    category: TicketCategory
    source: TicketSource
    created_by_id: uuid.UUID
    assigned_to_id: Optional[uuid.UUID]
    created_at: datetime
    updated_at: datetime
    resolved_at: Optional[datetime]
    closed_at: Optional[datetime]
    reply_count: int
    first_response_time: Optional[int]
    resolution_time: Optional[int]
    tags: Optional[List[str]]
    custom_fields: Optional[Dict[str, Any]]
    
    # 关联信息
    created_by: Optional[Dict[str, Any]]
    assigned_to: Optional[Dict[str, Any]]
    
    @model_validator(mode='before')
    @classmethod
    def convert_user_objects(cls, values):
        """将User对象转换为字典"""
        if hasattr(values, '__dict__'):
            values = values.__dict__
            
        if 'created_by' in values and values['created_by'] is not None:
            if not isinstance(values['created_by'], dict):
                # 将User对象转换为字典
                user_obj = values['created_by']
                values['created_by'] = {
                    'id': getattr(user_obj, 'id', None),
                    'username': getattr(user_obj, 'username', None),
                    'email': getattr(user_obj, 'email', None),
                    'display_name': getattr(user_obj, 'display_name', None),
                    'role': getattr(user_obj, 'role', None),
                    'status': getattr(user_obj, 'status', None)
                }
        
        if 'assigned_to' in values and values['assigned_to'] is not None:
            if not isinstance(values['assigned_to'], dict):
                # 将User对象转换为字典
                user_obj = values['assigned_to']
                values['assigned_to'] = {
                    'id': getattr(user_obj, 'id', None),
                    'username': getattr(user_obj, 'username', None),
                    'email': getattr(user_obj, 'email', None),
                    'display_name': getattr(user_obj, 'display_name', None),
                    'role': getattr(user_obj, 'role', None),
                    'status': getattr(user_obj, 'status', None)
                }
        
        return values
    
    class Config:
        from_attributes = True
        arbitrary_types_allowed = True  # 允许任意类型，避免类型检查错误


class TicketReplyResponse(BaseModel):
    """工单回复响应模型"""
    id: uuid.UUID
    ticket_id: uuid.UUID
    user_id: uuid.UUID
    content: str
    is_internal: bool
    is_automated: bool
    created_at: datetime
    updated_at: datetime
    
    class Config:
        from_attributes = True
        arbitrary_types_allowed = True


class TicketStats(BaseModel):
    """工单统计信息模型"""
    total_tickets: int
    open_tickets: int
    in_progress_tickets: int
    resolved_tickets: int
    closed_tickets: int
    average_response_time: Optional[float]  # 平均响应时间（秒）
    average_resolution_time: Optional[float]  # 平均解决时间（秒）
    by_category: Dict[TicketCategory, int]
    by_priority: Dict[TicketPriority, int]
    by_status: Dict[TicketStatus, int]
    
    class Config:
        arbitrary_types_allowed = True


class TicketFilter(BaseModel):
    """工单筛选条件模型"""
    status: Optional[List[TicketStatus]] = None
    priority: Optional[List[TicketPriority]] = None
    category: Optional[List[TicketCategory]] = None
    assigned_to: Optional[uuid.UUID] = None
    created_by: Optional[uuid.UUID] = None
    tags: Optional[List[str]] = None
    created_after: Optional[datetime] = None
    created_before: Optional[datetime] = None
    search: Optional[str] = None
    
    class Config:
        arbitrary_types_allowed = True
